﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Web;
using BackstageMusiciansFriend;
using System.Text;
using System.Security.Cryptography.X509Certificates;
using ControlUsuarioWebNamespace;
using DBMethodsNamespace;
using ControlImportacionNamespace;
using ControlLogNamespace;
using ControlSesionNamespace;
using ControlTareaPendienteNamespace;
using System.Threading;

namespace BackstageMusiciansFriend
{
    public class PublicacionException : Exception
    {        
        public PublicacionException(string strMessage)
            : base(strMessage)
        {
           
        }
    }


    public class ControlPublicacionAsyncHandler : System.Web.IHttpAsyncHandler
    {
        private AsyncTaskDelegate del;
        protected delegate void AsyncTaskDelegate(HttpContext context);
        ControlPublicacion objHandlerPublicacion;

        TareaPendiente objTareaARealizar;

        public ControlPublicacionAsyncHandler()
        {
            objHandlerPublicacion = new ControlPublicacion();
        }

        public void ProcessRequest(HttpContext context)
        {
            try
            {
                objHandlerPublicacion.publicarProductosPendientes(objTareaARealizar);
                ControlLog.writeLog("[ControlPublicacionAsyncHandler:ProcessRequest] Publicacion finalizada OK");
            }
            catch(PublicacionException publEx)
            {
                ControlLog.writeLog("[ControlPublicacionAsyncHandler:ProcessRequest] Excepcion de PUBLICACION:" + publEx.Message);
                objTareaARealizar.actualizarEstado(publEx.Message, "ERROR");
                Thread.Sleep(60000);
            }
            catch(Exception ex)
            {
                ControlLog.writeLog("[ControlPublicacionAsyncHandler:ProcessRequest] Excepcion publicando productos pendientes: "+ex.Message);
            }
        }

        private void callbackPublicacion(IAsyncResult ar)
        {
            try
            {
                this.EndProcessRequest(ar);
                //   objTareaARealizar.finalizar();
                objTareaARealizar.actualizarEstado("Tarea terminada", "END_VISIBLE");
                ControlLog.writeLog("[ControlPublicacionAsyncHandler:callbackPublicacion] Liberando UNICA INSTANCIA...");
            }
            catch (ImportacionException ex)
            {
                ControlLog.writeLog("[ControlPublicacionAsyncHandler:callbackPublicacion] Excepcion finalizando tarea: " + ex.Message);
            }
        }


        public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object obj)
        {
            this.del = new AsyncTaskDelegate(ProcessRequest);
            objHandlerPublicacion = (ControlPublicacion)obj;
            AsyncCallback objCallBack = new AsyncCallback(callbackPublicacion);
            objTareaARealizar = new TareaPendiente();
            objTareaARealizar.crearTarea(ControlSesion.session(ControlSesion.UsuarioLogin), "Publicaciones", "Publicando productos pendientes:  [" + System.DateTime.Now.ToString() + "]");        
            return del.BeginInvoke(context, objCallBack, obj);
        }

        public void EndProcessRequest(IAsyncResult ar)
        {
            this.del.EndInvoke(ar);
        }

        public bool IsReusable { get { return true; } }
    }


    public class ControlPublicacion
    {
        string strCantidadDeReintentos;
        string strEspacioEntreReintentos;

        public ControlPublicacion()
        {
        }

        public ControlPublicacion(string strCantidadDeReintentosParam, string strEspacioEntreReintentosParam)
        {
            // TODO: Complete member initialization
            strCantidadDeReintentos = strCantidadDeReintentosParam;
            strEspacioEntreReintentos = strEspacioEntreReintentosParam;
            ControlLog.writeLog("[ControlPublicacion:ctor] Cantidad de Reintentos: " + strCantidadDeReintentos);
            ControlLog.writeLog("[ControlPublicacion:ctor] Espacio entre Reintentos: " + strEspacioEntreReintentos);

        }

        static string _sIdDeFoto;
       

     

        public static string obtenerLinkPublicacion(string sIdPublicacion)
        {
            StringBuilder sb = new StringBuilder();
            string _strLinkPublicacion = "";

            // used on each read operation
            byte[] buf = new byte[40000];

            HttpWebRequest requestForItem = (HttpWebRequest)HttpWebRequest.Create("https://api.mercadolibre.com/items/"+sIdPublicacion.Substring(7,sIdPublicacion.IndexOf("-")-7));
            /*requestForItem.ContentType = "application/json;";
            requestForItem.Accept = "application/json";*/
            requestForItem.Method = "GET";

            // execute the request
            HttpWebResponse response = (HttpWebResponse)requestForItem.GetResponse();

            // we will read data via the response stream
            Stream resStream = response.GetResponseStream();

            string tempString = null;
            int count = 0;

            do
            {
                // fill the buffer with data
                count = resStream.Read(buf, 0, buf.Length);

                // make sure we read some data
                if (count != 0)
                {
                    // translate from bytes to ASCII text
                    tempString = Encoding.ASCII.GetString(buf, 0, count);

                    // continue building the string
                    sb.Append(tempString);
                }
            }
            while (count > 0); // any more data to read?

            _strLinkPublicacion = sb.ToString();
            _strLinkPublicacion = _strLinkPublicacion.Substring(_strLinkPublicacion.IndexOf(",\"permalink\":") + 14, _strLinkPublicacion.IndexOf("\",\"thumbnail\":") - _strLinkPublicacion.IndexOf(",\"permalink\":") - 14);
            return _strLinkPublicacion;
        }
        /// <summary>
        /// Obtiene el SELLER ID desde Mercado Libre, para identificar la publicacion con el vendedor
        /// </summary>
        /// <param name="sToken">Access Token que te da ML</param>
        /// <returns>Devuelve un string con el seller ID</returns>
        public static string obtenerSellerId(string sToken)
        {
            StringBuilder sb = new StringBuilder();
            string _strSellerId = "";

            // used on each read operation
            byte[] buf = new byte[8192];

            string strURL = "https://api.mercadolibre.com/users/me?access_token="+sToken;
            HttpWebRequest requestForItem = (HttpWebRequest)HttpWebRequest.Create(strURL);
            /*requestForItem.ContentType = "application/json;";
            requestForItem.Accept = "application/json";*/
            requestForItem.Method = "GET";

            // execute the request
            HttpWebResponse response = (HttpWebResponse)requestForItem.GetResponse();

            // we will read data via the response stream
            Stream resStream = response.GetResponseStream();

            string tempString = null;
            int count = 0;

            do
            {
                // fill the buffer with data
                count = resStream.Read(buf, 0, buf.Length);

                // make sure we read some data
                if (count != 0)
                {
                    // translate from bytes to ASCII text
                    tempString = Encoding.ASCII.GetString(buf, 0, count);

                    // continue building the string
                    sb.Append(tempString);
                }
            }
            while (count > 0); // any more data to read?

            _strSellerId=sb.ToString();
            _strSellerId = _strSellerId.Substring(_strSellerId.IndexOf("{\"id\":") + 6, _strSellerId.IndexOf(",\"nickname\":") - (_strSellerId.IndexOf("{\"id\":") + 6));
            return _strSellerId;
        }




        public static string PublicarProductos(ProductML Prod, int iNroProd, string sToken)
        {
            int i = iNroProd,
                j = 0,
                contador = 0;

            string sPath = String.Empty,
                   sIDPicture = String.Empty,
                   sAuxCadena = String.Empty,
                   sID = String.Empty,
                   sURL = String.Empty,
                   sFile = String.Empty,
                   sSellerId = String.Empty;

            string[] sImgs = new string[3];

            if (iNroProd < 10)
                sFile = "000" + iNroProd.ToString() + "-0000";
            else
                sFile = "00" + iNroProd.ToString() + "-0000";

            ControlLog.writeLog("[Publicar Productos] Obteniendo Seller ID");
            try
            {
                #region SELLER ID
                sSellerId = ControlPublicacion.obtenerSellerId(sToken);
                #endregion
            }
            catch
            {
                throw new ArgumentException(" Error obteniendo el ID del vendedor ");
            }

            ControlLog.writeLog("[Publicar Productos] Seller ID = "+sSellerId);

            try
            {
                while (ControlImagen.ObtenerImagen(sFile, ref sPath))
                {
                    ControlLog.writeLog("[Publicar Productos] Control Imagen devolvio path  = " + sPath);
                    sAuxCadena = CargarImagenWebClient(sPath, sToken);
                    ControlLog.writeLog("[Publicar Productos] CargarImagen devolvio  = " + sAuxCadena);
                    if (sAuxCadena == "Error")
                    {
                        throw new InvalidOperationException("CargarImagen devolvio un error al subir las fotos a ML");
                    }
                    sID = sAuxCadena.Substring(0, sAuxCadena.IndexOf(';')); ;
                    sURL = sAuxCadena.Substring(sAuxCadena.IndexOf(';') + 1, (sAuxCadena.Length - 1 - sAuxCadena.IndexOf(';'))); ;
                    sImgs[j] = sURL;

                    if (sIDPicture == String.Empty)
                        sIDPicture = "{id:'" + sID + "',url:'" + sURL + "'}";
                    else
                        sIDPicture = sIDPicture + "," + "{id:'" + sID + "',url:'" + sURL + "'}";

                    contador++;
                    j++;
                    sFile = sFile.Substring(0, 5) + "000" + j.ToString();
                }




                ControlLog.writeLog("[Publicar Productos] Publicar Items");
                HttpWebRequest requestForItem = (HttpWebRequest)HttpWebRequest.Create("https://api.mercadolibre.com/items?access_token=" + sToken);
                requestForItem.ContentType = "application/json;";
                requestForItem.Accept = "application/json";
                requestForItem.Method = "POST";

                string sTituloPublicacion = Prod.Title;
                string sSubTituloPublicacion = Prod.Subtitle;
                string sCategoriaId = "MLA2879"; //"MLA3014";  //Categoria ya asignada por el cliente, NO TOCAR 
                string sModoCompra = "buy_it_now";
                string sTipoDePublicacion = "bronze"; //Hayq ue dejarlo en bronze, publicar es gratis la venta no
                string sMoneda = Prod.getCurrency(); //PABLO: Método que devuelve "ARS" para $ y "USD" para U$S
                string sCantidad = Prod.Quantity;
                string sPrecio = "";
                try
                {

                    ControlLog.writeLog("[PublicarProductos] Precio CSV de la publicación : " + Prod.Price);
                    sPrecio = Prod.Price.Substring(1, Prod.Price.Length - 4);
                }
                catch
                {
                    throw new InvalidDataException("El formato en la columna MONTO del .CSV esta erroneo, debe comenzar con un signo PESOS y debe tener al menos dos decimales separados con punto ");
                }


                ControlLog.writeLog("[PublicarProductos] Precio de la publicación : " + sPrecio);

                string sIDPublicador = sSellerId;
                string sEstadoDelArticulo = "new";
                string sAceptaMercadoPago = "false";



                using (StreamWriter writerForItem = new StreamWriter(requestForItem.GetRequestStream()))
                {
                    string strCadenaItem = "{\"site_id\":\"MLA\",\"title\":\"" + sTituloPublicacion +
                        "\",\"subtitle\":\"" + sSubTituloPublicacion +
                        "\",\"category_id\":\"" + sCategoriaId +
                        "\",\"buying_mode\":\"" + sModoCompra +
                        "\",\"listing_type_id\":\"" + sTipoDePublicacion +
                        "\",\"currency_id\":\"" + sMoneda +
                        "\",\"available_quantity\":\"" + sCantidad +
                        "\",\"price\":\"" + sPrecio +
                        "\",\"condition\":\"" + sEstadoDelArticulo +
                        "\",\"pictures\":[" + sIDPicture + "]" +
                        ",\"accepts_mercadopago\":\"" + sAceptaMercadoPago +
                        "\",\"non_mercado_pago_payment_methods\":[]," +
                        "\"seller_address\":\"\"}";

                    ControlLog.writeLog("[Publicar Productos] URL de pedido de publicacion = " + requestForItem.RequestUri.ToString());
                    ControlLog.writeLog("[Publicar Productos] Cadena a publicar = " + strCadenaItem);

                    writerForItem.Write(strCadenaItem);
                }

                string sItemId = "";
                try
                {
                    WebResponse responseForItem = requestForItem.GetResponse();
                    Stream streamForItem = responseForItem.GetResponseStream();
                    string jsonForItem = "";
                    StreamReader reader = new StreamReader(streamForItem);
                    jsonForItem = reader.ReadToEnd();

                    sItemId = jsonForItem.Substring(jsonForItem.IndexOf("id\":\"") + 5, 12);
                }
                catch (WebException webEx)
                {
                    WebResponse responseForItemException = webEx.Response;
                    Stream streamForItemException = responseForItemException.GetResponseStream();
                    StreamReader readerException = new StreamReader(streamForItemException);
                    ControlLog.writeLog("[Publicar Productos] Excepcion PUBLICANDO ITEM = " + readerException.ReadToEnd());
                    throw webEx;
                }


                HttpWebRequest requestForDescription = (HttpWebRequest)HttpWebRequest.Create("https://api.mercadolibre.com/items/" + sItemId + "/descriptions?access_token=" + sToken);
                requestForDescription.ContentType = "application/json;";
                requestForDescription.Accept = "application/json";
                requestForDescription.Method = "POST";


                string[] strArrHTMLMarquee = ControlPublicacion.obtenerHTMLDeMarquesinas(Prod);
                string[] strArrHTMLPictures = ControlPublicacion.obtenerHTMLDeFotos(sImgs);

                string sDescripcionArticulo = strArrHTMLMarquee[0] +
                                              strArrHTMLMarquee[1] + "</br>" +
                                              Prod.Text_1 + "</br>" +
                                              strArrHTMLMarquee[2] +
                                              "<font size=\"5\" face=\"arial\" color=\"red\">" + Prod.Title + "</font></br>" +
                                              strArrHTMLPictures[0] + "</br>" + "</br>" +
                                              Prod.Header + "</br>" +
                                              "<strong>Descripción<strong><br/>" + "</br>" +
                                              Prod.Description + "</br>" +
                                              strArrHTMLPictures[1] + "</br>" +
                                              strArrHTMLPictures[2] +
                                              "<strong>Características<strong><br/>" +
                                              Prod.Features + "</br>" +
                                              "<strong>Especificaciones<strong><br/>" +
                                              Prod.Specifications + "</br>" + "</br>" +
                                              Prod.Text_2 + "</br>" +
                                              strArrHTMLMarquee[3] +
                                              strArrHTMLMarquee[4] +
                                              strArrHTMLMarquee[5] +
                                              strArrHTMLMarquee[6] +
                                              strArrHTMLMarquee[7] +
                                              strArrHTMLMarquee[8] +
                                              strArrHTMLMarquee[9] + "</br>" +
                                              Prod.Text_3;


                ControlLog.writeLog("[Publicar Productos] Descripción Item = " + sDescripcionArticulo);

                using (StreamWriter writerForDescription = new StreamWriter(requestForDescription.GetRequestStream()))
                {
                    writerForDescription.Write("{text:'" + sDescripcionArticulo + "'}");
                }

                WebResponse responseForDescription = requestForDescription.GetResponse();
                Stream streamForDescription = responseForDescription.GetResponseStream();

                string jsonForDescription = "";
                StreamReader readerForDescription = new StreamReader(streamForDescription);
                jsonForDescription = readerForDescription.ReadToEnd();


                ControlLog.writeLog("[Publicar Productos] Resultado final  = " + jsonForDescription);
                return jsonForDescription;


            }
            catch (WebException webExGeneral)
            {
                WebResponse responseException = webExGeneral.Response;
                Stream streamException = responseException.GetResponseStream();
                StreamReader readerException = new StreamReader(streamException);
                ControlLog.writeLog("[Publicar Productos] Web Exception General = " + readerException.ReadToEnd());
                throw webExGeneral;
            }
            catch (Exception Ex)
            {
                ControlLog.writeLog("[Publicar Productos] EXCEPCION PUBLICANDO ARTICULO  = " + Ex.Message);
                return Ex.Message;
            }
        }

        /// <summary>
        /// Obtiene el HTML a colocar en la descripcion según si la foto existe o no
        /// </summary>
        /// <param name="sImgs">String Array con los path de las fotos</param>
        /// <returns>Devuelve un string Array con las lineas HTML, una por foto</returns>
        private static string[] obtenerHTMLDeFotos(string[] sImgs)
        {

            string[] strArrHTMLPicture = new string[3];
            if (sImgs[0] == String.Empty)
            {
                strArrHTMLPicture[0] = "";
            }
            else
            {
                strArrHTMLPicture[0] = "<img src=" + sImgs[0] + "></img></br>";
            }
            if (sImgs[1] == String.Empty)
            {
                strArrHTMLPicture[1] = "";
            }
            else
            {
                strArrHTMLPicture[1] = "<img src=" + sImgs[1] + "></img></br>";
            }
            if (sImgs[2] == String.Empty)
            {
                strArrHTMLPicture[2] = "";
            }
            else
            {
                strArrHTMLPicture[2] = "<img src=" + sImgs[2] + "></img></br>";
            }
            return strArrHTMLPicture;
        }

        private static string[] obtenerHTMLDeMarquesinas(ProductML objProducto)
        {
            string[] strArrHTMLMarquee = new string[10];
            if (objProducto.Marquee_1 == String.Empty)
            {
                strArrHTMLMarquee[0] = "";
            }
            else
            {
                strArrHTMLMarquee[0] = "<img src=" + objProducto.Marquee_1 + "></img></br>";
            }
            if (objProducto.Marquee_2 == String.Empty)
            {
                strArrHTMLMarquee[1] = "";
            }
            else
            {
                strArrHTMLMarquee[1] = "<img src=" + objProducto.Marquee_2 + "></img></br>";
            }
            if (objProducto.Marquee_3 == String.Empty)
            {
                strArrHTMLMarquee[2] = "";
            }
            else
            {
                strArrHTMLMarquee[2] = "<img src=" + objProducto.Marquee_3 + "></img></br>";
            }
            if (objProducto.Marquee_4 == String.Empty)
            {
                strArrHTMLMarquee[3] = "";
            }
            else
            {
                strArrHTMLMarquee[3] = "<img src=" + objProducto.Marquee_4 + "></img></br>";
            }
            if (objProducto.Marquee_5 == String.Empty)
            {
                strArrHTMLMarquee[4] = "";
            }
            else
            {
                strArrHTMLMarquee[4] = "<img src=" + objProducto.Marquee_5 + "></img></br>";
            }
            if (objProducto.Marquee_6 == String.Empty)
            {
                strArrHTMLMarquee[5] = "";
            }
            else
            {
                strArrHTMLMarquee[5] = "<img src=" + objProducto.Marquee_6 + "></img></br>";
            }
            if (objProducto.Marquee_7 == String.Empty)
            {
                strArrHTMLMarquee[6] = "";
            }
            else
            {
                strArrHTMLMarquee[6] = "<img src=" + objProducto.Marquee_7 + "></img></br>";
            }
            if (objProducto.Marquee_8 == String.Empty)
            {
                strArrHTMLMarquee[7] = "";
            }
            else
            {
                strArrHTMLMarquee[7] = "<img src=" + objProducto.Marquee_8 + "></img></br>";
            }
            if (objProducto.Marquee_9 == String.Empty)
            {
                strArrHTMLMarquee[8] = "";
            }
            else
            {
                strArrHTMLMarquee[8] = "<img src=" + objProducto.Marquee_9 + "></img></br>";
            }
            if (objProducto.Marquee_10 == String.Empty)
            {
                strArrHTMLMarquee[9] = "";
            }
            else
            {
                strArrHTMLMarquee[9] = "<img src=" + objProducto.Marquee_10 + "></img></br>";
            }
            return strArrHTMLMarquee;
        }

        private static string obtenerContactoVendedor()
        {
            string _strContactoVendedor;

            _strContactoVendedor = " \"contact\":\"MYNAME\",\"other_info\":\"OTHER_INFO\", \"area_code\":\"011\",\"phone\":\"15-4-220000\",\"area_code2\":\"\",\"phone2\":\"\",\"email\":\"test@mytest.com\",\"webpage\":\"\"\"";
            return _strContactoVendedor;
        }

        private static bool bypassAllCertificateStuff(object sender, X509Certificate cert, X509Chain chain, System.Net.Security.SslPolicyErrors error)
        {
            return true;
        }

        private static string CargarImagenWebClient(string sFilePath, string sToken)
        {
            string sID = "Error";

            try
            {
                WebClient _objWebClient = new WebClient();
                byte[] byteArrResponse = new byte[2048];
                string strResponse = "";

                ControlLog.writeLog("[CargarImagen] Preparando el UploadFile a URL = " + "https://api.mercadolibre.com/sites/MLA/pictures?access_token=" + sToken+ "\r\nArchivo: "+sFilePath);
                _objWebClient.Headers.Add(HttpRequestHeader.ContentType, "image/jpg");

                ServicePointManager.ServerCertificateValidationCallback += new System.Net.Security.RemoteCertificateValidationCallback(bypassAllCertificateStuff);

                byteArrResponse = _objWebClient.UploadFile("https://api.mercadolibre.com/sites/MLA/pictures?access_token=" + sToken, null, sFilePath);

                strResponse = System.Text.Encoding.ASCII.GetString(byteArrResponse);
                ControlLog.writeLog("[CargarImagen] Respuesta fue " + strResponse);

                if (strResponse.Contains("id")) //Contiene datos validos
                {
                    try
                    {
                        sID = strResponse.Substring(strResponse.IndexOf("\"id\":\"") + 6, strResponse.IndexOf("\",\"quality\"") - (strResponse.IndexOf("\"id\":\"") + 6));
                        sID = sID + ';';
                        sID = sID + strResponse.Substring(strResponse.IndexOf("variations") + 38, strResponse.IndexOf("\",\"secure_url\"") - (strResponse.IndexOf("variations") + 38));
                    }
                    catch (Exception ee)
                    {

                        ControlLog.writeLog("[CargarImagen] Excepcion adquiriendo ID de foto  = " + ee.Message);
                    }
                }
                else
                {
                    ControlLog.writeLog("[CargarImagen] No contiene datos validos! (No se encontro \"id\") ");
                }
                
                
            }
            catch (Exception ee)
            {

                ControlLog.writeLog("[CargarImagen] Excepcion subiendo foto  = " + ee.Message);
            }

            ControlLog.writeLog("[CargarImagen] Se retorna el id = "+sID);
            return sID;
        }
         //HZ v2.0.4.6
        public void publicarProductosPendientes(TareaPendiente objCurrentTask)
        {
            DBMethods objConnection = new DBMethods();
            List<ControlImportacionProductoML> lstProductosPendientesDePublicacion = new List<ControlImportacionProductoML>();
            string strEstadoUltimoProductoPublicado = "";
            ControlPublicacionProductoML objProductoAnterior = null;
            int intProductoIndex = 0;
            try
            {
                lstProductosPendientesDePublicacion = objConnection.obtenerPublicacionesPendientes(ControlSesion.session(ControlSesion.UsuarioLogin));
                foreach (ControlImportacionProductoML objProductoAPublicar in lstProductosPendientesDePublicacion)
                {
                    ControlPublicacionProductoML objProducto = new ControlPublicacionProductoML(objProductoAPublicar);
                        try
                        {
                            if (strEstadoUltimoProductoPublicado == String.Empty)
                            {
                                objCurrentTask.actualizarEstado("Publicando producto #" + intProductoIndex.ToString() + " " + objProducto.getTitulo(), "En curso");
                            }
                            else if(strEstadoUltimoProductoPublicado == "OK")
                            {
                                objCurrentTask.actualizarEstado("Publicando producto #" + intProductoIndex.ToString() + " " + objProducto.getTitulo() + " - Producto anterior (" + objProductoAnterior.getTitulo() + ") publicado OK!", "En curso");
                            }
                            else
                            {
                                objCurrentTask.actualizarEstado("Publicando producto #" + intProductoIndex.ToString() + " " + objProducto.getTitulo() + " - ERROR Publicando producto anterior (" + objProductoAnterior.getTitulo() + ")", "En curso");
                            }

                           
                            
                            
                            if (this.publicarProducto(objProducto))
                            {
                                ControlLog.writeLog("[publicarProductosPendientes] Publicacion OK! IdML:"+objProducto.getIdMl());                                                      
                                objConnection.finalizarPublicacionPendiente(objProductoAPublicar);
                                objConnection.guardarPublicacionOk(objProducto);
                            }
                            else
                            {
                                ControlLog.writeLog("[publicarProductosPendientes] WARNING: La publicacion salio con error y por su naturaleza NO SE REINTENTARA ");                      
                                objConnection.GuardarPublicacionKo(objProducto);
                            }
                            intProductoIndex++;
                            objProductoAnterior = objProducto;

                        }
                        catch (Exception innerEx)
                        {
                            ControlLog.writeLog("[publicarProductosPendientes] InnerException: "+ innerEx.Message);                         
                        }
             
             
                }
            }
            catch (PublicacionException publEx)
            {
                ControlLog.writeLog("[publicarProductosPendientes] Excepcion de PUBLICACION: " + publEx.Message);
                throw publEx;
            }
            catch (Exception ex)
            {
                ControlLog.writeLog("[publicarProductosPendientes] Excepcion publicando producto" + ex.Message);
                throw ex;
            }

        }
        private int getDemoraEntreIntentos()
        {
            ControlLog.writeLog("[getDemoraEntreIntentos] Demora: " + strEspacioEntreReintentos);
            return Convert.ToInt32(strEspacioEntreReintentos);
        }
        private int getIntentosPosibles()
        {
              ControlLog.writeLog("[getIntentosPosibles] Reintentos: " + strCantidadDeReintentos);
            return Convert.ToInt32(strCantidadDeReintentos);   
        }
        //HZ v2.0.4.6
        private bool publicarProducto(ControlPublicacionProductoML objProductoAPublicar)
        {
            #region SELLER ID
            do
            {

                ControlLog.writeLog("[publicarProducto] Obteniendo Seller ID");
                try
                {
                    this.obtenerSellerId(objProductoAPublicar);
                    break;
                }
                catch (WebException webEx)
                {
                    ControlLog.writeLog("[publicarProducto] WebException en Seller ID (" + webEx.Status.ToString() + "): " + webEx.Message);
                    objProductoAPublicar.agregarError("Error web en SellerID: " + webEx.Status.ToString() + " Mensaje: " + webEx.Message);
                    objProductoAPublicar.incrementarIntentosRealizados();
                    ControlLog.writeLog("[publicarProducto] Se reintentara por " + objProductoAPublicar.getIntentosRealizados().ToString() + " vez en " + this.getDemoraEntreIntentos().ToString() + " segundos");
                    Thread.Sleep(this.getDemoraEntreIntentos() * 1000);

                }
                catch (Exception ex)
                {
                    ControlLog.writeLog("[publicarProducto] Excepcion en Seller ID:" + ex.Message);
                    objProductoAPublicar.agregarError("Error general en SellerID: " + ex.Message);
                    objProductoAPublicar.incrementarIntentosRealizados();
                    ControlLog.writeLog("[publicarProducto] Se reintentara por " + objProductoAPublicar.getIntentosRealizados().ToString() + " vez en " + this.getDemoraEntreIntentos().ToString() + " segundos");
                    Thread.Sleep(this.getDemoraEntreIntentos() * 1000);

                }
            }
            while (objProductoAPublicar.getIntentosRealizados() < this.getIntentosPosibles());

            if (objProductoAPublicar.getIntentosRealizados() == this.getIntentosPosibles())
            {
                ControlLog.writeLog("[publicarProducto] WARNING: Cantidad de reintentos sobre pasados obteniendo Seller ID (" + objProductoAPublicar.getIntentosRealizados().ToString() + ") ");
                objProductoAPublicar.agregarError("Error de reintentos obteniendo Seller ID: Se realizaron " + objProductoAPublicar.getIntentosRealizados().ToString() + " sin exito ");
                return false;
            }


            objProductoAPublicar.reiniciarReintentosRealizados();
            #endregion
            #region SUBIR IMAGENES
            do
            {
                    try
                    {
                        foreach (ControlImportacionProductoMLImagen objImagen in objProductoAPublicar.getImagenesDePublicacion())
                        {
                            ControlLog.writeLog("[publicarProducto] Path de imagen a subir a ML= " + objImagen.strLinkImagenLocal);
                            string strIdImagenCruda = this.subirImagenEnML(objImagen.strLinkImagenLocal, ControlSesion.session(ControlSesion.AccessToken));
                            objProductoAPublicar.agregarImagenJSON("{id:'" + strIdImagenCruda.Substring(0, strIdImagenCruda.IndexOf(';')) + "',url:'" + strIdImagenCruda.Substring(strIdImagenCruda.IndexOf(';') + 1, (strIdImagenCruda.Length - 1 - strIdImagenCruda.IndexOf(';'))) + "'}");
                        }
                        break;
                    }
                    catch (WebException webEx)
                    {
                        ControlLog.writeLog("[publicarProducto] WebException subiendo imagen (" + webEx.Status.ToString() + "): " + webEx.Message);
                        objProductoAPublicar.agregarError("Error web subiendo imagen: " + webEx.Status.ToString() + " Mensaje: " + webEx.Message);
                        objProductoAPublicar.incrementarIntentosRealizados();
                        ControlLog.writeLog("[publicarProducto] Se reintentara por " + objProductoAPublicar.getIntentosRealizados().ToString() + " vez en " + this.getDemoraEntreIntentos().ToString() + " segundos");
                        Thread.Sleep(this.getDemoraEntreIntentos() * 1000);

                    }
                    catch (Exception ex)
                    {
                        ControlLog.writeLog("[publicarProducto] Excepcion subiendo imagen:" + ex.Message);
                        objProductoAPublicar.agregarError("Error general subiendo imagen: " + ex.Message);
                        objProductoAPublicar.incrementarIntentosRealizados();
                        ControlLog.writeLog("[publicarProducto] Se reintentara por " + objProductoAPublicar.getIntentosRealizados().ToString() + " vez en " + this.getDemoraEntreIntentos().ToString() + " segundos");
                        Thread.Sleep(this.getDemoraEntreIntentos() * 1000);

                    }        
            }
            while (objProductoAPublicar.getIntentosRealizados() < this.getIntentosPosibles());

            if (objProductoAPublicar.getIntentosRealizados() == this.getIntentosPosibles())
            {
                ControlLog.writeLog("[publicarProducto] WARNING: Cantidad de reintentos sobre pasados subiendo imagen (" + objProductoAPublicar.getIntentosRealizados().ToString() + ") ");
                objProductoAPublicar.agregarError("Error de reintentos subiendo imagen: Se realizaron " + objProductoAPublicar.getIntentosRealizados().ToString() + " sin exito ");
                return false;
            }

            objProductoAPublicar.reiniciarReintentosRealizados();
            #endregion
            #region SUBIR ESQUELETO DE PRODUCTO
            do
            {
                try
                {
                    this.publicarEsqueleto(objProductoAPublicar, ControlSesion.session(ControlSesion.AccessToken));                    
                    
                    break;
                }
                catch (WebException webEx)
                {
                    ControlLog.writeLog("[publicarProducto] WebException subiendo esqueleto (" + webEx.Status.ToString() + "): " + webEx.Message);
                    objProductoAPublicar.agregarError("Error web subiendo esqueleto: " + webEx.Status.ToString() + " Mensaje: " + webEx.Message);
                    objProductoAPublicar.incrementarIntentosRealizados();
                    ControlLog.writeLog("[publicarProducto] Se reintentara por " + objProductoAPublicar.getIntentosRealizados().ToString() + " vez en " + this.getDemoraEntreIntentos().ToString() + " segundos");
                    Thread.Sleep(this.getDemoraEntreIntentos() * 1000);

                }
                catch (Exception ex)
                {
                    ControlLog.writeLog("[publicarProducto] Excepcion subiendo esqueleto:" + ex.Message);
                    objProductoAPublicar.agregarError("Error general subiendo esqueleto: " + ex.Message);
                    objProductoAPublicar.incrementarIntentosRealizados();
                    ControlLog.writeLog("[publicarProducto] Se reintentara por " + objProductoAPublicar.getIntentosRealizados().ToString() + " vez en " + this.getDemoraEntreIntentos().ToString() + " segundos");
                    Thread.Sleep(this.getDemoraEntreIntentos() * 1000);

                }
            }
            while (objProductoAPublicar.getIntentosRealizados() < this.getIntentosPosibles());

            if (objProductoAPublicar.getIntentosRealizados() == this.getIntentosPosibles())
            {
                ControlLog.writeLog("[publicarProducto] WARNING: Cantidad de reintentos sobre pasados subiendo esqueleto (" + objProductoAPublicar.getIntentosRealizados().ToString() + ") ");
                objProductoAPublicar.agregarError("Error de reintentos subiendo esqueleto: Se realizaron " + objProductoAPublicar.getIntentosRealizados().ToString() + " sin exito ");
                return false;
            }

            objProductoAPublicar.reiniciarReintentosRealizados();
         
            #endregion
            #region SUBIR DESCRIPCION DEL ITEM
            do
            {
                try
                {
                    this.publicarDescripcionDelItem(objProductoAPublicar, ControlSesion.session(ControlSesion.AccessToken));

                    break;
                }
                catch (WebException webEx)
                {
                    ControlLog.writeLog("[publicarProducto] WebException subiendo descripcion del item (" + webEx.Status.ToString() + "): " + webEx.Message);
                    objProductoAPublicar.agregarError("Error web subiendo descripcion del item: " + webEx.Status.ToString() + " Mensaje: " + webEx.Message);
                    objProductoAPublicar.incrementarIntentosRealizados();
                    ControlLog.writeLog("[publicarProducto] Se reintentara por " + objProductoAPublicar.getIntentosRealizados().ToString() + " vez en " + this.getDemoraEntreIntentos().ToString() + " segundos");
                    Thread.Sleep(this.getDemoraEntreIntentos() * 1000);

                }
                catch (Exception ex)
                {
                    ControlLog.writeLog("[publicarProducto] Excepcion subiendo descripcion del item:" + ex.Message);
                    objProductoAPublicar.agregarError("Error general subiendo descripcion del item: " + ex.Message);
                    objProductoAPublicar.incrementarIntentosRealizados();
                    ControlLog.writeLog("[publicarProducto] Se reintentara por " + objProductoAPublicar.getIntentosRealizados().ToString() + " vez en " + this.getDemoraEntreIntentos().ToString() + " segundos");
                    Thread.Sleep(this.getDemoraEntreIntentos() * 1000);

                }
            }
            while (objProductoAPublicar.getIntentosRealizados() < this.getIntentosPosibles());

            if (objProductoAPublicar.getIntentosRealizados() == this.getIntentosPosibles())
            {
                ControlLog.writeLog("[publicarProducto] WARNING: Cantidad de reintentos sobre pasados subiendo descripcion del item (" + objProductoAPublicar.getIntentosRealizados().ToString() + ") ");
                objProductoAPublicar.agregarError("Error de reintentos subiendo descripcion del item: Se realizaron " + objProductoAPublicar.getIntentosRealizados().ToString() + " sin exito ");
                return false;
            }

            objProductoAPublicar.reiniciarReintentosRealizados();
         
            #endregion
            #region OBTENER LINK DE PUBLICACION
            do
            {
                try
                {
                    this.obtenerLinkPublicacion(objProductoAPublicar);
                    break;
                }
                catch (WebException webEx)
                {
                    ControlLog.writeLog("[publicarProducto] WebException obteniendo link de publicacion: (" + webEx.Status.ToString() + "): " + webEx.Message);
                    objProductoAPublicar.agregarError("Error web obteniendo link de publicacion: " + webEx.Status.ToString() + " Mensaje: " + webEx.Message);
                    objProductoAPublicar.incrementarIntentosRealizados();
                    ControlLog.writeLog("[publicarProducto] Se reintentara por " + objProductoAPublicar.getIntentosRealizados().ToString() + " vez en " + this.getDemoraEntreIntentos().ToString() + " segundos");
                    Thread.Sleep(this.getDemoraEntreIntentos() * 1000);

                }
                catch (Exception ex)
                {
                    ControlLog.writeLog("[publicarProducto] Excepcion obteniendo link de publicacion:" + ex.Message);
                    objProductoAPublicar.agregarError("Error general obteniendo link de publicacion: " + ex.Message);
                    objProductoAPublicar.incrementarIntentosRealizados();
                    ControlLog.writeLog("[publicarProducto] Se reintentara por " + objProductoAPublicar.getIntentosRealizados().ToString() + " vez en " + this.getDemoraEntreIntentos().ToString() + " segundos");
                    Thread.Sleep(this.getDemoraEntreIntentos() * 1000);

                }
            }
            while (objProductoAPublicar.getIntentosRealizados() < this.getIntentosPosibles());

            if (objProductoAPublicar.getIntentosRealizados() == this.getIntentosPosibles())
            {
                ControlLog.writeLog("[publicarProducto] WARNING: Cantidad de reintentos sobre pasados obteniendo link de publicacion: (" + objProductoAPublicar.getIntentosRealizados().ToString() + ") ");
                objProductoAPublicar.agregarError("Error de reintentos obteniendo link de publicacion:: Se realizaron " + objProductoAPublicar.getIntentosRealizados().ToString() + " sin exito ");
                return false;
            }

            objProductoAPublicar.reiniciarReintentosRealizados();
            #endregion
            return true;
        }
        //HZ v2.0.4.6
        private void publicarDescripcionDelItem(ControlPublicacionProductoML objProductoAPublicar, string strAcessTokenParam)
        {
            string strJSONResponse = "";
            HttpWebRequest requestForDescription = (HttpWebRequest)HttpWebRequest.Create("https://api.mercadolibre.com/items/" + objProductoAPublicar.getItemId() + "/descriptions?access_token=" + strAcessTokenParam);
            requestForDescription.ContentType = "application/json;";
            requestForDescription.Accept = "application/json";
            requestForDescription.Method = "POST";

            ControlLog.writeLog("[publicarDescripcionDelItem] URL=" + "https://api.mercadolibre.com/items/" + objProductoAPublicar.getItemId() + "/descriptions?access_token=" + strAcessTokenParam);


            try
            {
                string[] strArrHTMLMarquee = this.obtenerHTMLDeMarquesinas(objProductoAPublicar);
                string[] strArrHTMLPictures = this.obtenerHTMLDeFotos(objProductoAPublicar);


                string strDescripcionArticulo;

                if (objProductoAPublicar.isHTMLDescription())
                {
                    strDescripcionArticulo = objProductoAPublicar.getDescripcionHTML();
                }
                else
                {
                    strDescripcionArticulo = strArrHTMLMarquee[0] +
                                              strArrHTMLMarquee[1] + "</br>" +
                                              objProductoAPublicar.getText(0) + "</br>" +
                                              strArrHTMLMarquee[2] +
                                              "<font size=\"5\" face=\"arial\" color=\"red\">" + objProductoAPublicar.getTitulo() + "</font></br>" +
                                              strArrHTMLPictures[0] + "</br>" + "</br>" +
                                              objProductoAPublicar.getHeader() + "</br>" +
                                              "<strong>" + objProductoAPublicar.getDescriptionTitle() + "<strong><br/>" + "</br>" +
                                              objProductoAPublicar.getDescripcion() + "</br>" +
                                              strArrHTMLPictures[1] + "</br>" +
                                              strArrHTMLPictures[2] +
                                              "<strong>" + objProductoAPublicar.getFeaturesTitle() + "<strong><br/>" +
                                              objProductoAPublicar.getFeatures() + "</br>" +
                                              "<strong>" + objProductoAPublicar.getSpecificationsTitle() + "<strong><br/>" +
                                              objProductoAPublicar.getSpecifications() + "</br>" + "</br>" +
                                              objProductoAPublicar.getText(1) + "</br>" +
                                              strArrHTMLMarquee[3] +
                                              strArrHTMLMarquee[4] +
                                              strArrHTMLMarquee[5] +
                                              strArrHTMLMarquee[6] +
                                              strArrHTMLMarquee[7] +
                                              strArrHTMLMarquee[8] +
                                              strArrHTMLMarquee[9] + "</br>" +
                                              objProductoAPublicar.getText(2);
                }

                ControlLog.writeLog("[publicarDescripcionDelItem] Descripción Item = " + strDescripcionArticulo);

                using (StreamWriter writerForDescription = new StreamWriter(requestForDescription.GetRequestStream()))
                {
                    writerForDescription.Write("{text:'" + strDescripcionArticulo + "'}");
                }

                WebResponse responseForDescription = requestForDescription.GetResponse();
                Stream streamForDescription = responseForDescription.GetResponseStream();

                
                StreamReader readerForDescription = new StreamReader(streamForDescription);
                strJSONResponse = readerForDescription.ReadToEnd();
            }
            catch (WebException webEx)
            {
                WebResponse responseForItemException = webEx.Response;
                Stream streamForItemException = responseForItemException.GetResponseStream();
                StreamReader readerException = new StreamReader(streamForItemException);                 
                throw new Exception("Error WEB publicando ITEM: " + readerException.ReadToEnd());                               
            }
            catch (Exception ex)
            {
                ControlLog.writeLog("[publicarDescripcionDelItem] Excepcion general PUBLICANDO DESCRIPCION DEL ITEM = " + ex.Message);
                throw ex;
            }

            objProductoAPublicar.setIdMl(strJSONResponse);
            ControlLog.writeLog("[publicarDescripcionDelItem] Resultado final  = " + strJSONResponse);
            
        }
        //HZ v2.0.4.6
        public void obtenerLinkPublicacion(ControlPublicacionProductoML objProductoAPublicar)
        {
            StringBuilder sb = new StringBuilder();       
            byte[] buf = new byte[40000];

            HttpWebRequest requestForItem = (HttpWebRequest)HttpWebRequest.Create("https://api.mercadolibre.com/items/" + objProductoAPublicar.getIdMl());
            ControlLog.writeLog("[obtenerLinkPublicacion] URL = " + "https://api.mercadolibre.com/items/" + objProductoAPublicar.getIdMl());            
            requestForItem.Method = "GET";

            try
            {

                HttpWebResponse response = (HttpWebResponse)requestForItem.GetResponse();
                Stream resStream = response.GetResponseStream();

                string strAuxiliar = null;
                int intCount = 0;

                do
                {
                    
                    intCount = resStream.Read(buf, 0, buf.Length);
                    if (intCount != 0)
                    {                        
                        strAuxiliar = Encoding.ASCII.GetString(buf, 0, intCount);                        
                        sb.Append(strAuxiliar);
                    }
                }
                while (intCount > 0); // any more data to read?

                strAuxiliar = sb.ToString();
                objProductoAPublicar.setLinkDePublicacion(strAuxiliar);
               
            }
            catch (WebException webEx)
            {
                WebResponse responseForItemException = webEx.Response;
                Stream streamForItemException = responseForItemException.GetResponseStream();
                StreamReader readerException = new StreamReader(streamForItemException);
                string strError = readerException.ReadToEnd();
                ControlLog.writeLog("[obtenerLinkPublicacion] WebException OBTENIENDO LINK = " + strError);
                throw new Exception("Error WEB OBTENIENDO LINK: " + strError);
            }
            catch (Exception ex)
            {
                ControlLog.writeLog("[obtenerLinkPublicacion] Excepcion general OBTENIENDO LINK  = " + ex.Message);
                throw ex;
            }

        }
        //HZ v2.0.4.6
        private void publicarEsqueleto(ControlPublicacionProductoML objProductoAPublicar, string strAccessTokenParam)
        {

            HttpWebRequest requestForItem = (HttpWebRequest)HttpWebRequest.Create("https://api.mercadolibre.com/items?access_token=" + strAccessTokenParam);
            ControlLog.writeLog("[publicarEsqueleto] URL=" + "https://api.mercadolibre.com/items?access_token=" + strAccessTokenParam);
            requestForItem.ContentType = "application/json;";
            requestForItem.Accept = "application/json";
            requestForItem.Method = "POST";
                

            try
            {
                using (StreamWriter writerForItem = new StreamWriter(requestForItem.GetRequestStream()))
                {
                    string strCadenaItem = "{\"site_id\":\"MLA\",\"title\":\"" + objProductoAPublicar.getTitulo() +
                        "\",\"subtitle\":\"" + objProductoAPublicar.getSubTitulo() +
                        "\",\"category_id\":\"" + objProductoAPublicar.getCategoria() +
                        "\",\"buying_mode\":\"" + objProductoAPublicar.getModoCompra() +
                        "\",\"listing_type_id\":\"" + objProductoAPublicar.getTipoDePublicacion() +
                        "\",\"currency_id\":\"" + objProductoAPublicar.getMoneda() +
                          objProductoAPublicar.getLinkYoutube() +                        
                        "\",\"available_quantity\":\"" + objProductoAPublicar.getCantidad() +
                        "\",\"price\":\"" + objProductoAPublicar.getPrecio() +
                        "\",\"condition\":\"" + objProductoAPublicar.getCondicionDelArticulo() +
                        "\",\"pictures\":[" + objProductoAPublicar.obtenerImagenesSubidasJSON() + "]" +
                        ",\"accepts_mercadopago\":\"" + objProductoAPublicar.obtenerAceptacionDeMercadoPago() +
                        "\",\"non_mercado_pago_payment_methods\":[]," +
                        "\"seller_address\":\"\"}";

                    ControlLog.writeLog("[publicarEsqueleto] JSON = " + strCadenaItem);

                    writerForItem.Write(strCadenaItem);
                }

            }
            catch (WebException webEx)
            {
                ControlLog.writeLog("[publicarEsqueleto] WebException PUBLICANDO ITEM (REQ) = " + webEx.Message);
                throw webEx;
            }
            catch (Exception ex)
            {
                ControlLog.writeLog("[publicarEsqueleto] Excepcion general publicando ITEM (REQ)  = " + ex.Message);
                throw ex;
            }

            ControlLog.writeLog("[publicarEsqueleto] Esperando respuesta... ");

            try
            {
                WebResponse responseForItem = requestForItem.GetResponse();
                Stream streamForItem = responseForItem.GetResponseStream();
                string jsonForItem = "";
                StreamReader reader = new StreamReader(streamForItem);
                jsonForItem = reader.ReadToEnd();

                objProductoAPublicar.setItemId(jsonForItem.Substring(jsonForItem.IndexOf("id\":\"") + 5, 12));
            }
            catch (WebException webEx)
            {
                WebResponse responseForItemException = webEx.Response;
                Stream streamForItemException = responseForItemException.GetResponseStream();
                StreamReader readerException = new StreamReader(streamForItemException);
                string strError = readerException.ReadToEnd();
                ControlLog.writeLog("[publicarEsqueleto] WebException PUBLICANDO ITEM (RESP) = " + strError);
                throw new Exception("Error WEB publicando ITEM: " + strError);
            }
            catch (Exception ex)
            {
                ControlLog.writeLog("[publicarEsqueleto] Excepcion general publicando ITEM (RESP)  = " + ex.Message);
                throw ex;
            }

        }
        //HZ v2.0.4.6
        private void obtenerSellerId(ControlPublicacionProductoML objProductoAPublicar)
        {
            string strSellerId = "";

            try
            {
                StringBuilder objBuilder = new StringBuilder();


                // used on each read operation
                byte[] buf = new byte[8192];

                string strURL = "https://api.mercadolibre.com/users/me?access_token=" + ControlSesion.session(ControlSesion.AccessToken);
                ControlLog.writeLog("[obtenerSellerId] URL = " + strURL);
                HttpWebRequest objRequest = (HttpWebRequest)HttpWebRequest.Create(strURL);
                objRequest.Method = "GET";
                HttpWebResponse objResponse = (HttpWebResponse)objRequest.GetResponse();
                Stream objStream = objResponse.GetResponseStream();

                int intCount = 0;

                do
                {
                    intCount = objStream.Read(buf, 0, buf.Length);
                    // make sure we read some data
                    if (intCount != 0)
                    {
                        objBuilder.Append(Encoding.ASCII.GetString(buf, 0, intCount));
                    }
                }
                while (intCount > 0); // any more data to read?

                strSellerId = objBuilder.ToString();
                strSellerId = strSellerId.Substring(strSellerId.IndexOf("{\"id\":") + 6, strSellerId.IndexOf(",\"nickname\":") - (strSellerId.IndexOf("{\"id\":") + 6));
                objProductoAPublicar.setSellerId(strSellerId);
            }
            catch (WebException webEx)
            {
                WebResponse responseForItemException = webEx.Response;
                Stream streamForItemException = responseForItemException.GetResponseStream();
                StreamReader readerException = new StreamReader(streamForItemException);
                string strError = readerException.ReadToEnd();
                ControlLog.writeLog("[obtenerSellerId] WebException OBTENIENDO LINK = " + strError);
                throw new Exception("Error WEB OBTENIENDO LINK: " + strError);
            }
            catch (Exception ex)
            {
                ControlLog.writeLog("[obtenerSellerId] Excepcion obteniendo Seller ID: " + ex.Message);
                throw ex;
            }
            return;
        }
        //HZ v2.0.4.6
        private string subirImagenEnML(string strFilePathParam,string strAccessTokenParam)
        {
            string strId = "Error";
            string strResponse = "";

            try
            {
                WebClient objWebClient = new WebClient();
                byte[] byteArrResponse = new byte[2048];
            
                ControlLog.writeLog("[subirImagenEnML] URL = " + "https://api.mercadolibre.com/sites/MLA/pictures?access_token=" + strAccessTokenParam);
                ControlLog.writeLog("[subirImagenEnML] Path Imagen = " + strFilePathParam);
                objWebClient.Headers.Add(HttpRequestHeader.ContentType, "image/jpg");

                ServicePointManager.ServerCertificateValidationCallback += new System.Net.Security.RemoteCertificateValidationCallback(bypassAllCertificateStuff);

                byteArrResponse = objWebClient.UploadFile("https://api.mercadolibre.com/sites/MLA/pictures?access_token=" + strAccessTokenParam, null, strFilePathParam);

                strResponse = System.Text.Encoding.ASCII.GetString(byteArrResponse);
                ControlLog.writeLog("[subirImagenEnML] Respuesta fue " + strResponse);
            }
            catch (WebException webEx)
            {
                WebResponse responseForItemException = webEx.Response;
                Stream streamForItemException = responseForItemException.GetResponseStream();
                StreamReader readerException = new StreamReader(streamForItemException);
                string strError = readerException.ReadToEnd();
                ControlLog.writeLog("[subirImagenEnML] WebException subiendo foto = " + strError);
                throw new Exception("Error WEB subiendo foto: " + strError);
            }
            catch (Exception ex)
            {
                ControlLog.writeLog("[subirImagenEnML] Exception subiendo foto " + ex.Message);
                throw ex;
            }

            if (strResponse.Contains("id")) //Contiene datos validos
            {
                try
                {
                    strId = strResponse.Substring(strResponse.IndexOf("\"id\":\"") + 6, strResponse.IndexOf("\",\"quality\"") - (strResponse.IndexOf("\"id\":\"") + 6));
                    strId = strId + ';';
                    strId = strId + strResponse.Substring(strResponse.IndexOf("variations") + 38, strResponse.IndexOf("\",\"secure_url\"") - (strResponse.IndexOf("variations") + 38));
                }
                catch (Exception ee)
                {
                    ControlLog.writeLog("[subirImagenEnML] Excepcion adquiriendo ID de foto  = " + ee.Message);
                    throw ee;
                }
            }
            else
            {
                ControlLog.writeLog("[subirImagenEnML] No contiene datos validos! (No se encontro \"id\") ");
                throw new PublicacionException("La respuesta que recibimos al subir la foto no tiene datos validos");
            }

            ControlLog.writeLog("[subirImagenEnML] Id de imagen= " + strId);
            return strId;
        }       
        //HZ v2.0.4.6
        public bool hayPublicacionesPendientes()
        {
            try
            {
                DBMethods objConnection = new DBMethods();
                if (objConnection.obtenerPublicacionesPendientes(ControlSesion.session(ControlSesion.UsuarioLogin)).Count == 0)
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }
            catch(Exception ex)
            {
                ControlLog.writeLog("[hayPublicacionesPendientes] Excepcion en DB: "+ex.Message);
                return false;
            }
        
        }
        //HZ v2.0.4.6
        private string[] obtenerHTMLDeMarquesinas(ControlPublicacionProductoML objProducto)
        {
            string[] strArrHTMLMarquee = new string[10];
            if (objProducto.getMarquee(0) == String.Empty)
            {
                strArrHTMLMarquee[0] = "";
            }
            else
            {
                strArrHTMLMarquee[0] = "<img src=" + objProducto.getMarquee(0) + "></img></br>";
            }
            if (objProducto.getMarquee(1) == String.Empty)
            {
                strArrHTMLMarquee[1] = "";
            }
            else
            {
                strArrHTMLMarquee[1] = "<img src=" + objProducto.getMarquee(1) + "></img></br>";
            }
            if (objProducto.getMarquee(2) == String.Empty)
            {
                strArrHTMLMarquee[2] = "";
            }
            else
            {
                strArrHTMLMarquee[2] = "<img src=" + objProducto.getMarquee(2) + "></img></br>";
            }
            if (objProducto.getMarquee(3) == String.Empty)
            {
                strArrHTMLMarquee[3] = "";
            }
            else
            {
                strArrHTMLMarquee[3] = "<img src=" + objProducto.getMarquee(3) + "></img></br>";
            }
            if (objProducto.getMarquee(4) == String.Empty)
            {
                strArrHTMLMarquee[4] = "";
            }
            else
            {
                strArrHTMLMarquee[4] = "<img src=" + objProducto.getMarquee(4) + "></img></br>";
            }
            if (objProducto.getMarquee(5) == String.Empty)
            {
                strArrHTMLMarquee[5] = "";
            }
            else
            {
                strArrHTMLMarquee[5] = "<img src=" + objProducto.getMarquee(5) + "></img></br>";
            }
            if (objProducto.getMarquee(6) == String.Empty)
            {
                strArrHTMLMarquee[6] = "";
            }
            else
            {
                strArrHTMLMarquee[6] = "<img src=" + objProducto.getMarquee(6) + "></img></br>";
            }
            if (objProducto.getMarquee(7) == String.Empty)
            {
                strArrHTMLMarquee[7] = "";
            }
            else
            {
                strArrHTMLMarquee[7] = "<img src=" + objProducto.getMarquee(7) + "></img></br>";
            }
            if (objProducto.getMarquee(8) == String.Empty)
            {
                strArrHTMLMarquee[8] = "";
            }
            else
            {
                strArrHTMLMarquee[8] = "<img src=" + objProducto.getMarquee(8) + "></img></br>";
            }
            if (objProducto.getMarquee(9) == String.Empty)
            {
                strArrHTMLMarquee[9] = "";
            }
            else
            {
                strArrHTMLMarquee[9] = "<img src=" + objProducto.getMarquee(9) + "></img></br>";
            }
            return strArrHTMLMarquee;            
        }
        //HZ v2.0.4.6
        private string[] obtenerHTMLDeFotos(ControlPublicacionProductoML objProducto)
        {

            string[] strArrHTMLPicture = new string[3];
            if (objProducto.getHtmlImage(0) == String.Empty)
            {
                strArrHTMLPicture[0] = "";
            }
            else
            {
                strArrHTMLPicture[0] = "<img src=" + objProducto.getHtmlImage(0) + "></img></br>";
            }

            if (objProducto.getHtmlImage(1) == String.Empty)
            {
                strArrHTMLPicture[1] = "";
            }
            else
            {
                strArrHTMLPicture[1] = "<img src=" + objProducto.getHtmlImage(1) + "></img></br>";
            }

            if (objProducto.getHtmlImage(2) == String.Empty)
            {
                strArrHTMLPicture[2] = "";
            }
            else
            {
                strArrHTMLPicture[2] = "<img src=" + objProducto.getHtmlImage(2) + "></img></br>";
            }

            return strArrHTMLPicture;
        }
    }
}
public class ControlPublicacionProductoML
{
    ControlImportacionProductoML objProductoPendiente;
    int intIntentosRealizados;
    string strIdML;
    string strSellerId;
    string strItemId;
	public string FechaPublicacion { get; set; }
    string strLinkDePublicacion;
    bool boolHayError;
    List<string> lstMensajeDeError;
    List<string> lstJSONImages;

    public override string ToString()
    {
        string strResultado="";

        /*
            objHTMFile.Write("<tr>" +
                                 "<td width=\"400px\"><b>Titulo</b></td>" +                                 
                                 "<td width=\"400px\"><b>ID Ml</b></td>" +
                                 "<td width=\"400px\"><b>Link de Publicacion</b></td>"+
                                 "<td width=\"400px\"><b>Errores encontrados</b></td>" +  
                                 "</tr>");
         */
        strResultado = "<tr>";
        strResultado += "<td>"+objProductoPendiente.Title+"</td>";
        if (strIdML == String.Empty)
        {
            strResultado += "<td style=\"color:Red\">El producto no fue publicado por haberse encontrado errores</td>";
        }
        else
        {
             strResultado += "<td>"+strIdML+"</td>";
        }
        if (strLinkDePublicacion == String.Empty)
        {
            strResultado += "<td style=\"color:Red\">El producto no fue publicado por haberse encontrado errores</td>";
        }
        else
        {
            strResultado += "<td><a href=\"" + strLinkDePublicacion + "\">"+strLinkDePublicacion+"</a></td>";
        }
        if (lstMensajeDeError.Count == 0)
        {
            strResultado += "<td style=\"color:Green\">No hay errores</td>";
        }
        else
        {
            strResultado += "<td>";
            foreach (string strError in lstMensajeDeError)
            {
                strResultado += "["+strError+"]";
            }
            strResultado += "</td>";    
                
        }
        strResultado += "</tr>";
        return strResultado;
    }

    public ControlPublicacionProductoML(ControlImportacionProductoML objProductoPendienteParam)
    {
        objProductoPendiente = objProductoPendienteParam;
        intIntentosRealizados = 0;
        lstMensajeDeError = new List<string>();
        lstJSONImages = new List<string>();
        boolHayError = false;
    }

    internal string getTitulo()
    {
        if (objProductoPendiente.Title == null)
        {
            return "Sin titulo";
        }

        return objProductoPendiente.Title;
    }

    internal string getSubTitulo()
    {
        if (objProductoPendiente.Subtitle == null)
        {
            return "Sin subtitulo";
        }
        return objProductoPendiente.Subtitle;
    }

    internal string getCantidad()
    {
        if (objProductoPendiente.Quantity == null)
        {
            return String.Empty;
        }
        return objProductoPendiente.Quantity;
    }

    internal string getPrecio()
    {
        ControlLog.writeLog("[getPrecio:ControlPublicacionProductoML] Precio del producto pendiente = "+objProductoPendiente.Price);
        try
        {
            if (objProductoPendiente.Price.StartsWith("$"))
            {
                //objProductoPendiente.Price = objProductoPendiente.Price.Substring(1, objProductoPendiente.Price.Length - 4);
                objProductoPendiente.Price = objProductoPendiente.Price.Substring(1, objProductoPendiente.Price.Length - 1);              
                ControlLog.writeLog("[getPrecio:ControlPublicacionProductoML] Precio FINAL del producto pendiente = " + objProductoPendiente.Price);
     
            }
        }
        catch(Exception ex)
        {
            ControlLog.writeLog("[getPrecio:ControlPublicacionProductoML] Excepcion preparando PRECIO: "+ex.Message);
        }

        return objProductoPendiente.Price;
      //  return "159";
    }

    public string getIdMl()
    {
        return strIdML;
    }

    internal string getLinkDePublicacion()
    {
        return strLinkDePublicacion;
    }

    public void setSellerId(string strSellerIdParam)
    {
        ControlLog.writeLog("[setSellerId] Seller Id = " + strSellerIdParam);
        strSellerId = strSellerIdParam;
    }

    public void agregarError(string strMensajeDeErrorParam)
    {
        boolHayError = true;
        ControlLog.writeLog("[agregarError] Agregando error = " + strMensajeDeErrorParam);
        lstMensajeDeError.Add(strMensajeDeErrorParam);
    }

    public string GetIdDbPublicacion()
    {
        return objProductoPendiente.intIdPublicacion.ToString();
    }

    public int getIntentosRealizados()
    {
        return intIntentosRealizados;
    }


    internal void incrementarIntentosRealizados()
    {
        intIntentosRealizados++;
    }

    internal string GetErrores()
    {
        string strErrores="";

        foreach (string strError in lstMensajeDeError)
        {
            strErrores +=  strError +"\r\n";
        }

        return strErrores.Replace("'","*");
    }

    internal List<ControlImportacionProductoMLImagen> getImagenesDePublicacion()
    {
        return objProductoPendiente.obtenerImagenes();
    }

    internal void agregarImagenJSON(string strJSONImageParam)
    {
        ControlLog.writeLog("[agregarImagenJSON] Agregando: "+strJSONImageParam);
        lstJSONImages.Add(strJSONImageParam);
    }

    internal string obtenerImagenesSubidasJSON()
    {
        string strJSON = "";
        if (lstJSONImages.Count > 0) //HZ v2.1.1.0
        {
            ControlLog.writeLog("[obtenerImagenesSubidasJSON] Existen " + lstJSONImages.Count.ToString() + " imagenes"); //HZ v2.1.1.0
            foreach (string strImagen in lstJSONImages)
            {
                strJSON += strImagen + ",";
            }

            ///Hacemos el substring para sacar la ultima COMA de mas...
            return strJSON.Substring(0, strJSON.Length - 1);
        }
        else //HZ v2.1.1.0
        {
            ControlLog.writeLog("[obtenerImagenesSubidasJSON] No existen imagenes: " + lstJSONImages.Count.ToString());//HZ v2.1.1.0
            return strJSON;//HZ v2.1.1.0
        }
        
        
    }

    internal void reiniciarReintentosRealizados()
    {
        ControlLog.writeLog("[reiniciarReintentosRealizados] Se reinicia a CERO la cantidad de intentos");
        intIntentosRealizados = 0;
    }

    internal string getCategoria()
    {
        return objProductoPendiente.Categoria;
      //  return "MLA2879";
    }

    internal string getModoCompra()
    {
        return "buy_it_now";
    }

    internal string getTipoDePublicacion()
    {
        return "bronze";
    }

    internal string getMoneda()
    {
        return objProductoPendiente.getCurrency();
    }
    /*
     condition	
    Estado
    new         	    Nuevo
    used	            Usado
    unespecified	    Sin especificar
     
     */
    internal string getCondicionDelArticulo()
    {
        ///HZ v2.1.1.0
        if (objProductoPendiente.Condicion == null)
        {
            ControlLog.writeLog("[getCondicionDelArticulo] WARNING: objProductoPendiente.Condicion = NULL "); ///HZ v2.1.1.0
            return "not_specified";
        }

        if (objProductoPendiente.Condicion == "N")
        {
            ControlLog.writeLog("[getCondicionDelArticulo] Condicion: NUEVO "); ///HZ v2.1.1.0
            return "new";
        }
        else if (objProductoPendiente.Condicion == "U")
        {
            ControlLog.writeLog("[getCondicionDelArticulo] Condicion: USADO "); ///HZ v2.1.1.0
            return "used";
        }
        else
        {
            ControlLog.writeLog("[getCondicionDelArticulo] Condicion: No Especificado "); ///HZ v2.1.1.0
            return "not_specified";
        }
    }

    internal string getDescripcionHTML()
    {
        return objProductoPendiente.HtmlDescription;
    }

    internal bool isHTMLDescription()
    {
        return objProductoPendiente.htmlMode;
    }

    internal string obtenerAceptacionDeMercadoPago()
    {
        return "false";
    }

    internal void setItemId(string strItemIdParam)
    {
        strItemId= strItemIdParam;
    }

    internal string getItemId()
    {
        return strItemId;
    }

    internal string getLinkYoutube()
    {
        string strJSONLine = "";

        if (objProductoPendiente.VideoLinkYouTube != null && objProductoPendiente.VideoLinkYouTube != String.Empty)
        {
           strJSONLine = "\",\"video_id\":\"" + objProductoPendiente.VideoLinkYouTube;
        }

        return strJSONLine;
    }

    internal string getMarquee(int intMarqueeIndex)
    {
        string strResult = null;
        
        switch (intMarqueeIndex)
        {
            case 0:
                strResult = objProductoPendiente.Marquee_1;
                break;
            case 1:
                strResult = objProductoPendiente.Marquee_2;
                break;
            case 2:
                strResult = objProductoPendiente.Marquee_3;
                break;
            case 3:
                strResult = objProductoPendiente.Marquee_4;
                break;
            case 4:
                strResult = objProductoPendiente.Marquee_5;
                break;
            case 5:
                strResult = objProductoPendiente.Marquee_6;
                break;
            case 6:
                strResult = objProductoPendiente.Marquee_7;
                break;
            case 7:
                strResult = objProductoPendiente.Marquee_8;
                break;
            case 8:
                strResult = objProductoPendiente.Marquee_9;
                break;
            case 9:
                strResult = objProductoPendiente.Marquee_10;
                break;
        }

        if (strResult == null)
        {
            throw new Exception("El indice de MARQUESINA recibido ("+intMarqueeIndex.ToString() +") no es valido para la cantidad de marquesinas configuradas");
        }
        return strResult;
    }

    internal string getHtmlImage(int intImageIndexParam)
    {
        string strResult = String.Empty;
        try
        {
            strResult = objProductoPendiente.obtenerImagenes()[intImageIndexParam].strLinkImagen;
        }
        catch(Exception ex)
        {
            ControlLog.writeLog("[getHtmlImage] EXCEPCION: No existe el indice (" + intImageIndexParam.ToString() + ") para la cantidad de imagenes configuradas. " + ex.Message);
            
        }

        return strResult;
    }

    internal string getText(int intIndexTextParam)
    {
        string strResult = null;

        switch (intIndexTextParam)
        {
            case 0:
                strResult = objProductoPendiente.Text_1;
                
                break;
            case 1:
                strResult = objProductoPendiente.Text_2;
                break;
            case 2:
                strResult = objProductoPendiente.Text_3;
                break;
            default:
                throw new Exception("No existe el indice (" + intIndexTextParam.ToString() + ") para la cantidad de textos configurados. ");

        }

        if (strResult == null)
        {
            strResult = String.Empty;
        }       

        return strResult;
    }

    internal string getHeader()
    {
        if (objProductoPendiente.Header == null)
        {
            return String.Empty;
        }
        return objProductoPendiente.Header;
    }

    internal string getDescriptionTitle()
    {
        if (objProductoPendiente.DescriptionTitle == null)
        {
            return String.Empty;
        }
        return objProductoPendiente.DescriptionTitle;
    }

    internal string getFeaturesTitle()
    {
        if (objProductoPendiente.FeatureTitle == null)
        {
            return String.Empty;
        }
        return objProductoPendiente.FeatureTitle;
    }

    internal string getSpecificationsTitle()
    {
        if (objProductoPendiente.SpecificationsTitle == null)
        {
            return String.Empty;
        }
        return objProductoPendiente.SpecificationsTitle;
    }

    internal string getDescripcion()
    {
        if (objProductoPendiente.Description == null)
        {
            return String.Empty;
        }
        return objProductoPendiente.Description;
    }

    internal string getFeatures()
    {
        if (objProductoPendiente.Features == null)
        {
            return String.Empty;
        }
        return objProductoPendiente.Features;
    }

    internal string getSpecifications()
    {
        if (objProductoPendiente.Specifications == null)
        {
            return String.Empty;
        }
        return objProductoPendiente.Specifications;
    }

    internal void setIdMl(string strJSONResponseParam)
    {
        ControlLog.writeLog("[setIdMl] Respuesta obtenida: " + strJSONResponseParam);
        strIdML = strJSONResponseParam.Substring(7, strJSONResponseParam.IndexOf("-") - 7);
        ControlLog.writeLog("[setIdMl] Id de ML Obtenido: " + strJSONResponseParam);
        
    }

    internal void setIdMlDirecto(string strJSONResponseParam)
    {
        strIdML = strJSONResponseParam;
        ControlLog.writeLog("[setIdMlDirecto] Id de ML Obtenido: " + strJSONResponseParam);
    }

    internal void setLinkDePublicacion(string strLinkDePublicacionCrudoParam)
    {
       strLinkDePublicacion = strLinkDePublicacionCrudoParam.Substring(strLinkDePublicacionCrudoParam.IndexOf(",\"permalink\":") + 14, strLinkDePublicacionCrudoParam.IndexOf("\",\"thumbnail\":") - strLinkDePublicacionCrudoParam.IndexOf(",\"permalink\":") - 14);
       ControlLog.writeLog("[setLinkDePublicacion] Link de publicacion = " + strLinkDePublicacion);
    }

    internal void setLinkDePublicacionDirecto(string strLinkDePublicacionCrudoParam)
    {
        strLinkDePublicacion = strLinkDePublicacionCrudoParam;
        ControlLog.writeLog("[setLinkDePublicacionDirecto] Link de publicacion = " + strLinkDePublicacion);
        
    }

    internal void SetFechaDePublicacion(string strFechaPublicacionParam)
    {
        FechaPublicacion = strFechaPublicacionParam;
    }

    internal void setErrores(string strErroresParam)
    {
        lstMensajeDeError.Clear();
        lstMensajeDeError.Add(strErroresParam);
    }
}
